package com.grq.framework.dameng.service;

import cn.hutool.extra.spring.SpringUtil;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.SqlId;
import org.beetl.sql.core.page.DefaultPageRequest;
import org.beetl.sql.core.page.PageResult;
import org.beetl.sql.core.query.LambdaQuery;
import org.beetl.sql.core.query.Query;
import org.beetl.sql.mapper.BaseMapper;
import org.springframework.beans.factory.annotation.Value;

import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

public abstract class BaseService<T> implements BaseMapper<T> {

    @Value("${beetlsql.beetlsqlManager.daoSuffix}")
    private String daoSuffix;

    private BaseMapper<T> baseMapper;

    public BaseMapper<T> getBaseMapper() {
        if (this.baseMapper == null) {
            ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();  // 反射
            String typeName = pt.getActualTypeArguments()[0].getTypeName(); // 获取第一个类型参数的真实类
            String daoName = typeName.substring(typeName.lastIndexOf(".") + 1);
            String entityDao = Character.toLowerCase(daoName.charAt(0)) + daoName.substring(1) + daoSuffix;
            this.baseMapper = SpringUtil.getBean(entityDao);
        }
        return this.baseMapper;
    }

    @Override
    public boolean exist(Object key) {
        return getBaseMapper().exist(key);
    }

    @Override
    public int insert(T entity) {
        return getBaseMapper().insert(entity);
    }

    @Override
    public int insertTemplate(T entity) {
        return getBaseMapper().insertTemplate(entity);
    }

    @Override
    public void insertBatch(List<T> list) {
        getBaseMapper().insertBatch(list);
    }

    @Override
    public int updateById(T entity) {
        return getBaseMapper().updateById(entity);
    }

    @Override
    public int updateTemplateById(T entity) {
        return getBaseMapper().updateTemplateById(entity);
    }

    @Override
    public boolean upsert(T entity) {
        return getBaseMapper().upsert(entity);
    }

    @Override
    public boolean upsertByTemplate(T entity) {
        return getBaseMapper().upsertByTemplate(entity);
    }

    @Override
    public int deleteById(Object key) {
        return getBaseMapper().deleteById(key);
    }

    @Override
    public T unique(Object key) {
        return getBaseMapper().unique(key);
    }

    @Override
    public T single(Object key) {
        return getBaseMapper().single(key);
    }

    @Override
    public List<T> selectByIds(List<?> key) {
        return getBaseMapper().selectByIds(key);
    }

    @Override
    public T lock(Object key) {
        return getBaseMapper().lock(key);
    }

    @Override
    public List<T> all() {
        return getBaseMapper().all();
    }

    @Override
    public long allCount() {
        return getBaseMapper().allCount();
    }

    @Override
    public List<T> template(T entity) {
        return getBaseMapper().template(entity);
    }

    @Override
    public T templateOne(T entity) {
        return getBaseMapper().templateOne(entity);
    }

    @Override
    public long templateCount(T entity) {
        return getBaseMapper().templateCount(entity);
    }

    @Override
    public List<T> execute(String sql, Object... args) {
        return getBaseMapper().execute(sql, args);
    }

    @Override
    public int executeUpdate(String sql, Object... args) {
        return getBaseMapper().executeUpdate(sql, args);
    }

    @Override
    public SQLManager getSQLManager() {
        return getBaseMapper().getSQLManager();
    }

    @Override
    public Query<T> createQuery() {
        return getBaseMapper().createQuery();
    }

    @Override
    public LambdaQuery<T> createLambdaQuery() {
        return getBaseMapper().createLambdaQuery();
    }

    @Override
    public Class<T> getTargetEntity() {
        return getBaseMapper().getTargetEntity();
    }

    @Override
    public int[] updateByIdBatch(List<?> list) {
        return getBaseMapper().updateByIdBatch(list);
    }

    @Override
    public int[] updateTemplateByIdBatch(List<?> list) {
        return getBaseMapper().updateTemplateByIdBatch(list);
    }

    @Override
    public void clearProperties(List<?> pks, LambdaQuery.Property<T, ?>... properties) {
        getBaseMapper().clearProperties(pks,properties);
    }

    public PageResult<T> pageQuery(String sqlId, Map<String, Object> paras, long page, int size) {
        return getSQLManager().pageQuery(SqlId.of(sqlId), getTargetEntity(), paras, DefaultPageRequest.of(page, size));
    }

    public List<T> query(String sqlId,Map<String, Object> paras){
        return getBaseMapper().getSQLManager().select(SqlId.of(sqlId),getTargetEntity(),paras);
    }
}
